package com.example.teaching_server.controller;

import com.example.teaching_server.common.ApiResponse;
import com.example.teaching_server.dto.CreateNoticeRequest;
import com.example.teaching_server.dto.NoticeDTO;
import com.example.teaching_server.dto.NoticeRequest;
import com.example.teaching_server.entity.NoticeEntity;
import com.example.teaching_server.entity.NoticeTypeEntity;
import com.example.teaching_server.service.NoticeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@Slf4j
@RestController
@RequestMapping("/api/notices")
@RequiredArgsConstructor
@Tag(name = "通知管理", description = "通知信息查询和管理接口")
public class NoticeController {

    private final NoticeService noticeService;

    /**
     * 获取通知列表
     */
    @GetMapping
    @Operation(summary = "获取通知列表", description = "根据用户ID和标签类型获取通知列表")
    public ApiResponse<List<NoticeDTO>> getNotices(
            @Parameter(description = "用户ID")
            @RequestParam Long userId,
            @Parameter(description = "标签类型：received或published")
            @RequestParam String tabType,
            @Parameter(description = "通知类型ID")
            @RequestParam(required = false) Long typeId,
            @Parameter(description = "页码")
            @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页大小")
            @RequestParam(defaultValue = "10") Integer size) {

        log.info("开始获取通知列表: userId={}, tabType={}, typeId={}, page={}, size={}",
                userId, tabType,typeId, page, size);

        try {
            NoticeRequest request = new NoticeRequest();
            request.setUserId(userId);
            request.setTabType(tabType);
            request.setTypeId(typeId);
            request.setPage(page);
            request.setSize(size);

            List<NoticeDTO> notices;
            if ("received".equals(tabType)) {
                notices = noticeService.getReceivedNotices(request);
            } else {
                notices = noticeService.getPublishedNotices(request);
            }

            log.info("成功获取{}个通知", notices.size());
            return ApiResponse.success("获取通知列表成功", notices);
        } catch (Exception e) {
            log.error("获取通知列表失败", e);
            return ApiResponse.fail("获取通知列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有通知类型
     */
    @GetMapping("/types")
    @Operation(summary = "获取通知类型", description = "获取所有可用的通知类型")
    public ApiResponse<List<NoticeTypeEntity>> getNoticeTypes() {
        log.info("开始获取通知类型");

        try {
            List<NoticeTypeEntity> types = noticeService.getAllNoticeTypes();
            log.info("成功获取{}个通知类型", types.size());
            return ApiResponse.success("获取通知类型成功", types);
        } catch (Exception e) {
            log.error("获取通知类型失败", e);
            return ApiResponse.fail("获取通知类型失败: " + e.getMessage());
        }
    }

    /**
     * 获取通知详情
     */
    @GetMapping("/{noticeId}")
    @Operation(summary = "获取通知详情", description = "根据通知ID获取通知详细信息")
    public ApiResponse<NoticeDTO> getNoticeDetail(
            @Parameter(description = "通知ID")
            @PathVariable Long noticeId,
            @Parameter(description = "标签类型")
            @RequestParam String tabType,
            @Parameter(description = "用户ID")
            @RequestParam Long userId) {

        log.info("开始获取通知详情: noticeId={}, tabType={}, userId={}", noticeId, tabType, userId);

        try {
            Optional<NoticeEntity> noticeOpt = noticeService.getNoticeById(noticeId);
            if (noticeOpt.isEmpty()) {
                log.warn("通知不存在: noticeId={}", noticeId);
                return ApiResponse.fail("通知不存在");
            }

            NoticeEntity notice = noticeOpt.get();
            NoticeDTO noticeDTO = convertToDTO(notice, userId, tabType);
            return ApiResponse.success("获取通知详情成功", noticeDTO);
        } catch (Exception e) {
            log.error("获取通知详情失败: noticeId={}", noticeId, e);
            return ApiResponse.fail("获取通知详情失败: " + e.getMessage());
        }
    }

    /**
     * 创建通知
     */
    @PostMapping
    @Operation(summary = "创建通知", description = "创建新的通知")
    public ApiResponse<NoticeDTO> createNotice(
            @RequestBody CreateNoticeRequest request,
            @Parameter(description = "用户ID")
            @RequestParam Long userId) {

        log.info("开始创建通知: userId={}, title={}", userId, request.getTitle());

        try {
            NoticeEntity notice = noticeService.createNotice(request, userId);
            NoticeDTO noticeDTO = convertToDTO(notice, userId, "published");
            log.info("通知创建成功: noticeId={}", notice.getNoticeId());
            return ApiResponse.success("通知创建成功", noticeDTO);
        } catch (Exception e) {
            log.error("创建通知失败", e);
            return ApiResponse.fail("创建通知失败: " + e.getMessage());
        }
    }

    /**
     * 更新通知
     */
    @PutMapping("/{noticeId}")
    @Operation(summary = "更新通知", description = "更新指定通知的信息")
    public ApiResponse<NoticeDTO> updateNotice(
            @Parameter(description = "通知ID")
            @PathVariable Long noticeId,
            @RequestBody CreateNoticeRequest request,
            @Parameter(description = "用户ID")
            @RequestParam Long userId) {

        log.info("开始更新通知: noticeId={}, userId={}", noticeId, userId);

        try {
            NoticeEntity notice = noticeService.updateNotice(noticeId, request, userId);
            NoticeDTO noticeDTO = convertToDTO(notice, userId, "published");
            log.info("通知更新成功: noticeId={}", noticeId);
            return ApiResponse.success("通知更新成功", noticeDTO);
        } catch (Exception e) {
            log.error("更新通知失败: noticeId={}", noticeId, e);
            return ApiResponse.fail("更新通知失败: " + e.getMessage());
        }
    }

    /**
     * 删除通知
     */
    @DeleteMapping("/{noticeId}")
    @Operation(summary = "删除通知", description = "删除指定的通知")
    public ApiResponse<String> deleteNotice(
            @Parameter(description = "通知ID")
            @PathVariable Long noticeId,
            @Parameter(description = "用户ID")
            @RequestParam Long userId) {

        log.info("开始删除通知: noticeId={}, userId={}", noticeId, userId);

        try {
            noticeService.deleteNotice(noticeId, userId);
            log.info("通知删除成功: noticeId={}", noticeId);
            return ApiResponse.success("通知删除成功");
        } catch (Exception e) {
            log.error("删除通知失败: noticeId={}", noticeId, e);
            return ApiResponse.fail("删除通知失败: " + e.getMessage());
        }
    }

    /**
     * 标记通知为已读
     */
    @PostMapping("/{noticeId}/read")
    @Operation(summary = "标记已读", description = "将通知标记为已读状态")
    public ApiResponse<String> markAsRead(
            @Parameter(description = "通知ID")
            @PathVariable Long noticeId,
            @Parameter(description = "用户ID")
            @RequestParam Long userId) {

        log.info("开始标记通知已读: noticeId={}, userId={}", noticeId, userId);

        try {
            noticeService.markNoticeAsRead(noticeId, userId);
            log.info("通知标记已读成功: noticeId={}", noticeId);
            return ApiResponse.success("标记已读成功");
        } catch (Exception e) {
            log.error("标记已读失败: noticeId={}", noticeId, e);
            return ApiResponse.fail("标记已读失败: " + e.getMessage());
        }
    }

    /**
     * 转换实体为DTO
     */
    private NoticeDTO convertToDTO(NoticeEntity notice, Long userId, String tabType) {
        NoticeDTO dto = new NoticeDTO();
        dto.setNoticeId(notice.getNoticeId());
        dto.setTitle(notice.getTitle());
        dto.setTypeId(notice.getTypeId());
        dto.setDescription(notice.getDescription());
        dto.setContent(notice.getContent());
        dto.setCreateTime(notice.getCreatedAt());
        dto.setScheduleId(notice.getScheduleId());
        return dto;
    }
}
